package org.assistant.common.jdbc.datasource;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.sql.DataSource;

import org.assistant.common.exception.InitDataSourceException;
import org.assistant.common.utils.ClassUtils;

public class DataSourceFactory {
	private static DataSourceConfig dataSourceConfig = null;// 数据库配置信息

	private DataSource dataSource = null;// 数据源

	private static DataSourceFactory instace;

	private DataSourceFactory() {
		if (dataSourceConfig == null) {
			dataSourceConfig = new DataSourceConfig();
		}
		// 创建数据源
		boolean jndi = dataSourceConfig.isJndi();
		if (!jndi) {// 数据库驱动数据源
			this.dataSource = getDataSourceByDriver();
		} else {
			// JNDI数据源
			this.dataSource = getDataSourceByJndi();
		}
	}

	public static DataSourceFactory getInstace() {
		if (instace == null) {
			instace = new DataSourceFactory();
		}
		return instace;
	}

	public DataSource getDataSource() {
		return this.dataSource;
	}

	/**
	 * 从数据库驱动中获取数据源
	 * 
	 * @return
	 * @throws ServletException
	 */
	protected DataSource getDataSourceByDriver() {
		String dataSourceClassName = dataSourceConfig.getDataSourceClassName();
		String driverClassName = dataSourceConfig.getDriverClassName();
		String url = dataSourceConfig.getUrl();
		String username = dataSourceConfig.getUsername();
		String password = dataSourceConfig.getPassword();

		DataSource dataSource = null;

		try {
			dataSource = (DataSource) ClassUtils
				.getInstance(dataSourceClassName);
		} catch (Exception e) {
			e.printStackTrace();
			throw new InitDataSourceException("创建数据源时出错：" + e.getMessage());
		}
		if (dataSource instanceof AbstractDriverBasedDataSource) {
			AbstractDriverBasedDataSource abstractDs = (AbstractDriverBasedDataSource) dataSource;
			abstractDs.setDriverClassName(driverClassName);
			abstractDs.setUrl(url);
			abstractDs.setUsername(username);
			abstractDs.setPassword(password);
		} else {
			throw new InitDataSourceException("未知的DataSource实现类[ "
					+ dataSourceClassName + " ]");
		}

		return dataSource;
	}

	/**
	 * 从JNDI中查找数据源
	 * 
	 * @return
	 * @throws ServletException
	 */
	protected DataSource getDataSourceByJndi() {
		String context = dataSourceConfig.getContext();
		String jndiName = dataSourceConfig.getJndiName();

		DataSource dataSource = null;
		try {
			InitialContext ctx = new InitialContext();
			Context envCtx = (Context) ctx.lookup(context);
			dataSource = (DataSource) envCtx.lookup(jndiName);
		} catch (NamingException e) {
			e.printStackTrace();
			throw new InitDataSourceException("查找JNDI数据源时出错：" + e.getMessage());
		}

		return dataSource;
	}
}
